{
  LW Panel -- LightWave Panel Services

  The Panels global supplies a set of routines for creating user interface
  windows from within plug-ins.

  Also see the related raster and context menu globals.

  Based on lwpanel.h which is:
  Copyright 1999, NewTek, Inc.
}

{
  Copyright 2012, Jameel Halabi

  This unit is part of the BlaiseWave wrapper,
  which is licensed under the BSD 2-Clause license (see licenses/license.txt).
}

unit LW_Panel;

{$mode objfpc}{$H+}

interface

uses
  LW_Render ,
  LW_Server ,
  LW_XPanel ;

const
  PANEL_SERVICES_NAME  = 'LWPanelServices 2'   ;
  LWPANELFUNCS_GLOBAL  = 'LWPanelServices 2'   ;
  LWRASTERFUNCS_GLOBAL = 'RasterServices'      ;
  LWCONTEXTMENU_GLOBAL = 'ContextMenuServices' ;
  LWPANELMENU_GLOBAL   = 'PanelMenuServices 1' ;
  LWPANELS_API_VERSION = 21 ;

  { Values are exchanged with controls by means of these wrappers }
  LWT_NULL     = 0           ;
  LWT_STRING   = 1           ;
  LWT_INTEGER  = 2           ;
  LWT_FLOAT    = 3           ;
  LWT_DISTANCE = 4           ;
  LWT_VINT     = 5           ;
  LWT_VFLOAT   = 6           ;
  LWT_VDIST    = 7           ;
  LWT_BOOLEAN  = 8           ;
  LWT_CHOICE   = 9           ;
  LWT_SURFACE  = 10          ;
  LWT_FONT     = 11          ;
  LWT_TEXT     = 12          ;
  LWT_LAYERS   = 13          ;
  LWT_CUSTOM   = 14          ;
  LWT_RANGE    = 15          ;
  LWT_LWITEM   = 16          ;
  LWT_PERCENT  = 17          ;
  LWT_POPUP    = 18          ;
  LWT_AREA     = 19          ;
  LWT_XPANEL   = 20          ;
  LWT_TREE     = 21          ;
  LWT_MLIST    = 22          ;
  LWT_POINTER  = 23          ;
  LWT__LAST    = LWT_POINTER ;

  { Tags to get/set panel attributes }
  // enum pTag
  PAN_X            =  0 ;
  PAN_Y            =  1 ;
  PAN_W            =  2 ;
  PAN_H            =  3 ;
  PAN_MOUSEX       =  4 ;
  PAN_MOUSEY       =  5 ;

  PAN_FLAGS        =  6 ;
  PAN_USERDRAW     =  7 ;
  PAN_USERACTIVATE =  8 ;

  PAN_USEROPEN     =  9 ;
  PAN_USERCLOSE    = 10 ;
  PAN_TITLE        = 11 ;
  PAN_USERDATA     = 12 ;
  PAN_USERKEYS     = 13 ;

  PAN_LWINSTANCE   = 14 ;
  PAN_MOUSEBUTTON  = 15 ;
  PAN_MOUSEMOVE    = 16 ;
  PAN_PANFUN       = 17 ;
  PAN_VERSION      = 18 ;
  PAN_RESULT       = 19 ;

  PAN_HOSTDISPLAY  = 20 ;
  PAN_USERKEYUPS   = 21 ;
  PAN_QUALIFIERS   = 22 ;
  PAN_TO_FRONT     = 23 ;

  PAN_MOUSEWHEEL   = 24 ;
  PAN_USERRESIZE   = 25 ;
  PAN_MIN_W        = 26 ;
  PAN_MIN_H        = 27 ;
  PAN_MAX_W        = 28 ;
  PAN_MAX_H        = 29 ;
  PAN_CONFIGTAG    = 30 ;

  // enum DrMode
  DR_ERASE   = 0 ;
  DR_RENDER  = 1 ;
  DR_GHOST   = 2 ;
  DR_REFRESH = 3 ;

  { Tags to get/set panel attributes }
  // enum cTag
  CTL_X             =  0 ;
  CTL_Y             =  1 ;
  CTL_W             =  2 ;
  CTL_H             =  3 ;
  CTL_VALUE         =  4 ;
  CTL_HOTX          =  5 ;
  CTL_HOTY          =  6 ;
  CTL_HOTW          =  7 ;
  CTL_HOTH          =  8 ;
  CTL_LABELWIDTH    =  9 ;
  CTL_MOUSEX        = 10 ;
  CTL_MOUSEY        = 11 ;
  CTL_FLAGS         = 12 ;
  CTL_USERDRAW      = 13 ;
  CTL_USEREVENT     = 14 ;
  CTL_LABEL         = 15 ;
  CTL_USERDATA      = 16 ;
  CTL_PANEL         = 17 ; // use these 2 to get your panelID and functions!
  CTL_PANFUN        = 18 ;
  CTL_RANGEMIN      = 19 ;
  CTL_RANGEMAX      = 20 ; // get/set slider range params  API 10 and later */
  CTL_ACTIVATE      = 21 ; // set only, to actvate/enter string controls   API 10 and later */
  CTL_MOUSEBUTTON   = 22 ; // get the mouse button pressed,  read only API 20 and later */
  CTL_SELECTEVENT   = 23 ; // set a callback for selection events
  CTL_MOUSECLICKCNT = 24 ; // check if double clicked

  { Tags to get mouse buttons for controls }
  // enum mBut
  CTL_MOUSELEFT     = 1 ;
  CTL_MOUSECENTER   = 2 ;
  CTL_MOUSERIGHT    = 3 ;

  // enum MxType
  MX_HCHOICE        = 0 ;
  MX_VCHOICE        = 1 ;
  MX_POPUP          = 2 ;

  PANELMENUFLAG_SELECTED   = 1 shl 0 ;
  PANELMENUFLAG_UNSELECTED = 1 shl 1 ;
  PANELMENUFLAG_HIGHLIGHT  = 1 shl 2 ;
  PANELMENUFLAG_DISABLED   = 1 shl 3 ;

  PANF_BLOCKING    = 1   ; // open waits for close, or returns immediately
  PANF_CANCEL      = 2   ; // Continue or Continue/Cancel
  PANF_FRAME       = 4   ; // Windowing System Title bar
  PANF_MOUSETRAP   = 8   ; // Please track mouse input and call mouse callbacks
  PANF_PASSALLKEYS = 16  ; // Pass Enter/Esc keys to panel, instead of closing with OK/Cancel
  PANF_ABORT       = 32  ; // Abort instead of Continue, usw w/ PANF_CANEL!!
  PANF_NOBUTT      = 64  ; // No Continue or Continue/Cancel
  PANF_RESIZE      = 128 ; // Allow resizing of window. Clients should reposition/recreate controls

  CTLF_DISABLE     = $100 ; // Read-Only ,i.e. check if button has been drawn w/DR_GHOST , or erase
  CTLF_INVISIBLE   = $200 ; // Read-Only        ... erased
  CTLF_GHOST       = CTLF_DISABLE ;

  LWI_IMAGE        = LWI_BONE  + 1 ;
  LWI_ANY          = LWI_IMAGE + 1 ;

  NODE_FLAG_EXPND  = 1    ; // TreeControl item expanded state
  NODE_FLAG_WRITE  = 1024 ; // TreeControl flag write-mode, allows clearing of other bits

  { w/EVNT_BLOCKING handle() won't return 'til panel is closed , w/out EVNT_BLOCKING, EVNT_ALL is irrelevant }
  EVNT_BLOCKING    = 1 ; // 1 << 0  i.e. bit flags  handle() method waits for input, or gives immediate return
  EVNT_ALL         = 2 ; // 1 << 1  if set, handle() method will poll entire queue of events,

  { Input qualifiers }
  IQ_CTRL      = 1   ;
  IQ_SHIFT     = 2   ;
  IQ_ALT       = 4   ;
  IQ_CONSTRAIN = 8   ;
  IQ_ADJUST    = 16  ;
  MOUSE_LEFT   = 32  ;
  MOUSE_MID    = 64  ;
  MOUSE_RIGHT  = 96  ;
  MOUSE_DOWN   = 128 ;
  // Defined as functions at the end
  // RCLICK(code)
  // LCLICK(code)
  // MCLICK(code)

type
  LWDualKey        = Word    ; // unsigned short
const
  { Input key codes }
  LWDK_F1       = LWDualKey ( $1001 ) ;
  LWDK_F2       = LWDualKey ( $1002 ) ;
  LWDK_F3       = LWDualKey ( $1003 ) ;
  LWDK_F4       = LWDualKey ( $1004 ) ;
  LWDK_F5       = LWDualKey ( $1005 ) ;
  LWDK_F6       = LWDualKey ( $1006 ) ;
  LWDK_F7       = LWDualKey ( $1007 ) ;
  LWDK_F8       = LWDualKey ( $1008 ) ;
  LWDK_F9       = LWDualKey ( $1009 ) ;
  LWDK_F10      = LWDualKey ( $100A ) ;
  LWDK_F11      = LWDualKey ( $100B ) ;
  LWDK_F12      = LWDualKey ( $100C ) ;

  LWDK_SC_LEFT  = LWDualKey ( $1010 ) ;
  LWDK_SC_RIGHT = LWDualKey ( $1011 ) ;
  LWDK_SC_UP    = LWDualKey ( $1012 ) ;
  LWDK_SC_DOWN  = LWDualKey ( $1013 ) ;

  LWDK_DELETE   = LWDualKey ( $1020 ) ;
  LWDK_HELP     = LWDualKey ( $1021 ) ;
  LWDK_RETURN   = LWDualKey ( $1022 ) ;

  LWDK_HOME     = LWDualKey ( $108F ) ;
  LWDK_END      = LWDualKey ( $1090 ) ;
  LWDK_PAGEUP   = LWDualKey ( $1091 ) ;
  LWDK_PAGEDOWN = LWDualKey ( $1092 ) ;

  LWDK_TOP_0    = LWDualKey ( $1030 ) ;
  LWDK_TOP_1    = LWDualKey ( $1031 ) ;
  LWDK_TOP_2    = LWDualKey ( $1032 ) ;
  LWDK_TOP_3    = LWDualKey ( $1033 ) ;
  LWDK_TOP_4    = LWDualKey ( $1034 ) ;
  LWDK_TOP_5    = LWDualKey ( $1035 ) ;
  LWDK_TOP_6    = LWDualKey ( $1036 ) ;
  LWDK_TOP_7    = LWDualKey ( $1037 ) ;
  LWDK_TOP_8    = LWDualKey ( $1038 ) ;
  LWDK_TOP_9    = LWDualKey ( $1039 ) ;

  LWDK_PAD_0    = LWDualKey ( $1040 ) ;
  LWDK_PAD_1    = LWDualKey ( $1041 ) ;
  LWDK_PAD_2    = LWDualKey ( $1042 ) ;
  LWDK_PAD_3    = LWDualKey ( $1043 ) ;
  LWDK_PAD_4    = LWDualKey ( $1044 ) ;
  LWDK_PAD_5    = LWDualKey ( $1045 ) ;
  LWDK_PAD_6    = LWDualKey ( $1046 ) ;
  LWDK_PAD_7    = LWDualKey ( $1047 ) ;
  LWDK_PAD_8    = LWDualKey ( $1048 ) ;
  LWDK_PAD_9    = LWDualKey ( $1049 ) ;

  LWDK_PAD_OPAREN  = LWDualKey ( $1050 ) ;
  LWDK_PAD_CPAREN  = LWDualKey ( $1051 ) ;
  LWDK_PAD_SLASH   = LWDualKey ( $1052 ) ;
  LWDK_PAD_STAR    = LWDualKey ( $1053 ) ;
  LWDK_PAD_DASH    = LWDualKey ( $1054 ) ;
  LWDK_PAD_PLUS    = LWDualKey ( $1055 ) ;
  LWDK_PAD_DECIMAL = LWDualKey ( $1056 ) ;
  LWDK_PAD_ENTER   = LWDualKey ( $1057 ) ;

  LWDK_ALT         = LWDualKey ( $1060 ) ;
  LWDK_SHIFT       = LWDualKey ( $1061 ) ;
  LWDK_CTRL        = LWDualKey ( $1062 ) ;

  { Color Definitions }
  SYSTEM_Ic     = 4136           ;
  LWP_NONE      = SYSTEM_Ic + 0  ;
  LWP_INVERT    = SYSTEM_Ic + 1  ;
  LWP_BG        = SYSTEM_Ic + 2  ;
  LWP_NORMAL    = SYSTEM_Ic + 3  ;
  LWP_HEADLINE  = SYSTEM_Ic + 4  ;
  LWP_INFO_BG   = SYSTEM_Ic + 5  ;
  LWP_INFO_IMG  = SYSTEM_Ic + 6  ;
  LWP_INFO_DIS  = SYSTEM_Ic + 7  ;
  LWP_EDIT_BG   = SYSTEM_Ic + 8  ;
  LWP_EDIT_IMG  = SYSTEM_Ic + 9  ;
  LWP_EDIT_SEL  = SYSTEM_Ic + 10 ;
  LWP_EDIT_DIS  = SYSTEM_Ic + 11 ;

  LWP_BLACK     = SYSTEM_Ic + 12 ;
  LWP_SHADOW    = SYSTEM_Ic + 13 ;
  LWP_LOWERED   = SYSTEM_Ic + 14 ;
  LWP_RAISED    = SYSTEM_Ic + 15 ;
  LWP_HILIGHT   = SYSTEM_Ic + 16 ;

  COLOR_BG        = LWP_BG        ;
  COLOR_DK_YELLOW = LWP_EDIT_IMG  ;
  COLOR_DK_GREY   = LWP_SHADOW    ;
  COLOR_LT_YELLOW = LWP_EDIT_SEL  ;
  // COLOR_MD_GREY   = LWP_B_FACE    ; // LWP_B_FACE Not defined on the LW SDK
  // COLOR_LT_GREY   = LWP_GLINT     ; // LWP_GLINT  Not defined on the LW SDK
  COLOR_BLACK     = LWP_NORMAL    ;
  COLOR_WHITE     = LWP_HEADLINE  ;

  LWP_0_STAT    = SYSTEM_Ic + 17 ;
  LWP_1_STAT    = SYSTEM_Ic + 18 ;
  LWP_2_STAT    = SYSTEM_Ic + 19 ;
  LWP_3_STAT    = SYSTEM_Ic + 20 ;
  LWP_4_STAT    = SYSTEM_Ic + 21 ;
  LWP_5_STAT    = SYSTEM_Ic + 22 ;
  LWP_0_DLOG    = SYSTEM_Ic + 23 ;
  LWP_1_DLOG    = SYSTEM_Ic + 24 ;
  LWP_2_DLOG    = SYSTEM_Ic + 25 ;
  LWP_3_DLOG    = SYSTEM_Ic + 26 ;
  LWP_4_DLOG    = SYSTEM_Ic + 27 ;
  LWP_5_DLOG    = SYSTEM_Ic + 28 ;
  LWP_0_DOIT    = SYSTEM_Ic + 29 ;
  LWP_1_DOIT    = SYSTEM_Ic + 30 ;
  LWP_2_DOIT    = SYSTEM_Ic + 31 ;
  LWP_3_DOIT    = SYSTEM_Ic + 32 ;
  LWP_4_DOIT    = SYSTEM_Ic + 33 ;
  LWP_5_DOIT    = SYSTEM_Ic + 34 ;
  LWP_0_DRAG    = SYSTEM_Ic + 35 ;
  LWP_1_DRAG    = SYSTEM_Ic + 36 ;
  LWP_2_DRAG    = SYSTEM_Ic + 37 ;
  LWP_3_DRAG    = SYSTEM_Ic + 38 ;
  LWP_4_DRAG    = SYSTEM_Ic + 39 ;
  LWP_5_DRAG    = SYSTEM_Ic + 40 ;
  LWP_1_BG      = SYSTEM_Ic + 41 ;
  LWP_2_BG      = SYSTEM_Ic + 42 ;
  LWP_3_BG      = SYSTEM_Ic + 43 ;

  { Allow LWPanels to access new color definitions - Matt Gorner (11.15.2010) }
  LWP_LABEL                  = SYSTEM_Ic + 69 ;
  LWP_WIN_BG                 = SYSTEM_Ic + 70 ;

  LWP_TREE_TITLE             = SYSTEM_Ic + 71 ;
  LWP_TREE_BODY              = SYSTEM_Ic + 72 ;

  LWP_BUTTON_OUTLINE         = SYSTEM_Ic + 73 ;
  LWP_BUTTON_HIGH            = SYSTEM_Ic + 74 ;
  LWP_BUTTON_SELECTED_TEXT   = SYSTEM_Ic + 75 ;
  LWP_BUTTON_LOW             = SYSTEM_Ic + 76 ;
  LWP_BUTTON_SELECTED_HILITE = SYSTEM_Ic + 77 ;
  LWP_TREE_TEXT              = SYSTEM_Ic + 78 ;

  { Same Palette different names (based on defaults)! }
  LWP_GRAY1      = SYSTEM_Ic +  7 ;
  LWP_GRAY2      = SYSTEM_Ic + 13 ;
  LWP_GRAY3      = SYSTEM_Ic +  1 ;
  LWP_GRAY4      = SYSTEM_Ic +  8 ;
  LWP_GRAY5      = SYSTEM_Ic +  5 ;
  LWP_GRAY6      = SYSTEM_Ic +  2 ;
  LWP_GRAY7      = SYSTEM_Ic + 11 ;
  LWP_GRAY8      = SYSTEM_Ic +  9 ;
  LWP_WHITE      = SYSTEM_Ic +  4 ;
  LWP_CANARY1    = SYSTEM_Ic + 17 ;
  LWP_CANARY2    = SYSTEM_Ic + 18 ;
  LWP_CANARY3    = SYSTEM_Ic + 19 ;
  LWP_CANARY4    = SYSTEM_Ic + 20 ;
  LWP_CANARY5    = SYSTEM_Ic + 21 ;
  LWP_CANARY6    = SYSTEM_Ic + 22 ;
  LWP_AQUA1      = SYSTEM_Ic + 23 ;
  LWP_AQUA2      = SYSTEM_Ic + 24 ;
  LWP_AQUA3      = SYSTEM_Ic + 25 ;
  LWP_AQUA4      = SYSTEM_Ic + 26 ;
  LWP_AQUA5      = SYSTEM_Ic + 27 ;
  LWP_AQUA6      = SYSTEM_Ic + 28 ;
  LWP_LAVENDER1  = SYSTEM_Ic + 29 ;
  LWP_LAVENDER2  = SYSTEM_Ic + 30 ;
  LWP_LAVENDER3  = SYSTEM_Ic + 31 ;
  LWP_LAVENDER4  = SYSTEM_Ic + 32 ;
  LWP_LAVENDER5  = SYSTEM_Ic + 33 ;
  LWP_LAVENDER6  = SYSTEM_Ic + 34 ;
  LWP_OLIVE1     = SYSTEM_Ic + 35 ;
  LWP_OLIVE2     = SYSTEM_Ic + 36 ;
  LWP_OLIVE3     = SYSTEM_Ic + 37 ;
  LWP_OLIVE4     = SYSTEM_Ic + 38 ;
  LWP_OLIVE5     = SYSTEM_Ic + 39 ;
  LWP_OLIVE6     = SYSTEM_Ic + 40 ;

type
  PLWControl       = ^TLWControl ;
  PLWPanel         = Pointer     ;
  PLWContextMenu   = Pointer     ;
  PLWPanelMenu     = Pointer     ;

  PLWDisplayMetrics = ^TLWDisplayMetrics ;
  TLWDisplayMetrics = record
    Width      ,
    Height     ,
    PixX       ,
    PixY       ,
    MaxColors  ,
    Depth      ,
    TextHeight ,
    TextAscent : Integer ;
  end;

  { Values are exchanged with controls by means of these wrappers }
  TLWType = Integer ;

  PLWValString = ^TLWValString ;
  TLWValString = record
    Type_      : TLWType ;
    Buf        : PChar   ; // locale specific encoding
    BufLen     : Integer ;
  end;

  PLWValInt = ^TLWValInt ;
  TLWValInt = record
    Type_      : TLWType ;
    Value      ,
    DefVal     : Integer ;
  end;

  PLWValFloat = ^TLWValFloat ;
  TLWValFloat = record
    Type_      : TLWType ;
    Value      ,
    DefVal     : Double  ;
  end;

  PLWValIVector = ^TLWValIVector ;
  TLWValIVector = record
    Type_      : TLWType ;
    Value      : array[0..2] of Integer ;
    DefVal     : Integer ;
  end;

  PLWValFVector = ^TLWValFVector ;
  TLWValFVector = record
    Type_      : TLWType ;
    Value      : array[0..2] of Double ;
    DefVal     : Double  ;
  end;

  PLWValCustom = ^TLWValCustom ;
  TLWValCustom = record
    Type_      : TLWType ;
    Value      : array[0..3] of Integer ;
  end;

  PLWValPointer = ^TLWValPointer ;
  TLWValPointer = record
    Type_      : TLWType ;
    Ptr        : Pointer ;
  end;

  PLWPanStringDesc = ^TLWPanStringDesc ;
  TLWPanStringDesc = record
    Type_      : TLWType ;
    Width      : Integer ;
  end;

  PLWPanChoiceDesc = ^TLWPanChoiceDesc ;
  TLWPanChoiceDesc = record
    Type_      : TLWType ;
    Items      : PPChar  ;
    Vertical   : Integer ;
  end;

  PLWPanTextDesc = ^TLWPanTextDesc ;
  TLWPanTextDesc = record
     Type_      : TLWType ;
     Text       : PPChar  ;
  end;

  PLWPanRangeDesc = ^TLWPanRangeDesc ;
  TLWPanRangeDesc = record
     Type_      : TLWType ;
     Width      ,
     Min        ,
     Max        : Integer ;
  end;

  PLWPanAreaDesc = ^TLWPanAreaDesc ;
  TLWPanAreaDesc = record
     Type_      : TLWType ;
     Width      ,
     Height     : Integer ;
  end;

  PLWPanLWItemDesc = ^TLWPanLWItemDesc ;
  TLWPanLWItemDesc = record
     Type_      : TLWType ;
     Global     : Pointer ;
     ItemType   : Integer ;
     List       : PPChar  ; // locale specific encoding (dependent on LWItemInfo and LWImageList) (client does not set this)
     Count      ,
     Width      : Integer ;
  end;

  PLWPanPopupDesc = ^TLWPanPopupDesc ;
  TLWPanPopupDesc = record
     Type_      : TLWType ;
     Width      ,           // Width in pixels
     VisItems   ,           // Height in items,
     Top        : Integer ; // Top visible item
     CountFn    : function
                  ( Control : Pointer ) : Integer ;
     NameFn     : function
                  ( Control : Pointer ;
                    Index   : Integer ) : PChar ;
  end;

  PLWPanListBoxDesc = ^TLWPanListBoxDesc ;
  TLWPanListBoxDesc = record
     Type_      : TLWType ;
     Width      ,           // Width in pixels
     VisItems   ,           // Height in items,
     Top        : Integer ; // Top visible item
     CountFn    : function
                  ( Control : Pointer ) : Integer ;
     NameFn     : function
                  ( Control : Pointer ;
                    Index   : Integer ) : PChar ; // return text in locale specific encoding
  end;

  PLWPanMultiListBoxDesc = ^TLWPanMultiListBoxDesc ;
  TLWPanMultiListBoxDesc = record
     Type_      : TLWType ;
     Width      ,           // Width in pixels
     VisItems   ,           // Height in items,
     Top        : Integer ; // Top visible item
     CountFn    : function
                  ( Control : Pointer ) : Integer ;
     NameFn     : function
                  ( Control : Pointer ;
                    Index   : Integer ) : PChar ; // item, column // return text in locale specific encoding
     ColWidth   : function
                  ( Control : Pointer ;
                    Index   : Integer ) : Integer ; // pixel width of column i, up to 8 columns terminate with 0
  end;

  PLWPanXPanDesc = ^TLWPanXPanDesc ;
  TLWPanXPanDesc = record
     Type_      : TLWType ;
     Width      ,           // Width in pixels
     Height     : Integer ; // Height in pixels ,
     XPanel     : Pointer ;
  end ;

  PLWPanTreeDesc = ^TLWPanTreeDesc ;
  TLWPanTreeDesc = record
     Type_      : TLWType ;
     Width      ,           // Width in pixels
     Height     : Integer ; // Height in pixels ,
     CountFn    : function
                  ( Data : Pointer ;
                    Node : Pointer ) : Integer ;  // return number of leafs under given node, NULL node is root
     LeafFn     : function
                  ( Data : Pointer ;
                    Node : Pointer ;
                    Leaf : Integer ) : Pointer ;  // return leaf i of node, NULL node is root
     InfoFn     : function
                  ( Data : Pointer ;
                    Node : Pointer ;
                    NodeFlags : Integer ) : PChar ;  // return "name" for node, fill 0 flags, or save non-zero flags // return text in locale specific encoding
     MoveFn     : procedure
                  ( Data     : Pointer ;
                    Node     ,
                    Parent   : Pointer ;
                    Position : Integer ) ;        // NULL prevents moves, or called when user moves node, with new parent, position */
  end;

  TLWPanHook       = procedure
                     (       PanelID    : PLWPanel  ;
                             UserData   : Pointer   ) ;
  TLWPanKeyHook    = function
                     (       PanelID    : PLWPanel  ;
                             UserData   : Pointer   ;
                             DualKey    : LWDualKey ) : Integer ;
  TLWPanMouseHook  = procedure
                     (       PanelID    : PLWPanel  ;
                             UserData   : Pointer   ;
                             Qualifiers ,             //see input qualifier bits
                             X          ,
                             Y          : Integer ) ;
  TLWPanDrawHook   = procedure
                     (       PanelID    : PLWPanel  ;
                             UserData   : Pointer   ;
                             DrawMode   : Integer   ) ; // Originally DrMode enum
  TLWPanResizeHook = procedure
                     (       PanelID    : PLWPanel  ;
                             UserData   : Pointer   ;
                             Width      ,               // Width in pixels
                             Height     : Integer   ) ; // Height in pixels
  TLWCtlDrawHook   = procedure
                     (       PanelID    : PLWPanel  ;
                             UserData   : Pointer   ;
                             DrawMode   : Integer   ) ; // Originally DrMode enum
  TLWCtlEventHook  = procedure
                     (       PanelID    : PLWPanel  ;
                             UserData   : Pointer   ) ;

  PLWValue = ^TLWValue ;
  TLWValue = record
     Case Integer of
      0 : ( Type_ : TLWType       ) ;
      1 : ( Str   : TLWValString  ) ;
      2 : ( IntV  : TLWValInt     ) ;
      3 : ( Flt   : TLWValFloat   ) ;
      4 : ( IVec  : TLWValIVector ) ;
      5 : ( FVec  : TLWValFVector ) ;
      6 : ( Ptr   : TLWValPointer ) ;
      7 : ( Cust  : TLWValCustom  ) ;
  end;

  PLWPanControlDesc = ^TLWPanControlDesc ;
  TLWPanControlDesc = record
    Case Integer of
      0  : ( Type_     : TLWType                 ) ;
      1  : ( String_   : TLWPanStringDesc        ) ;
      2  : ( Choice    : TLWPanChoiceDesc        ) ;
      3  : ( Text      : TLWPanTextDesc          ) ;
      4  : ( Range     : TLWPanRangeDesc         ) ;
      5  : ( Area      : TLWPanAreaDesc          ) ;
      6  : ( Lwitem    : TLWPanLWItemDesc        ) ;
      7  : ( Popup     : TLWPanPopupDesc         ) ;
      8  : ( Listbox   : TLWPanListBoxDesc       ) ;
      9  : ( Xpanel    : TLWPanXPanDesc          ) ;
      10 : ( Tree      : TLWPanTreeDesc          ) ;
      11 : ( MultiList : TLWPanMultiListBoxDesc  ) ;
    end;

  PDrawFuncs = ^TDrawFuncs ;
  TDrawFuncs = record
    DrawPixel    : procedure
                   (       PanelID  : PLWPanel ;
                           Color    ,
                           X        ,
                           Y        : Integer  ) ;
    DrawRGBPixel : procedure
                   (       PanelID  : PLWPanel ;
                           R        ,
                           G        ,
                           B        ,
                           X        ,
                           Y         : Integer ) ;
    DrawLine     : procedure
                   (       PanelID  : PLWPanel ;
                           Color    ,
                           X        ,
                           Y        ,
                           X2       ,
                           Y2       : Integer  ) ;
    DrawBox      : procedure
                   (       PanelID  : PLWPanel   ;
                           Color    ,
                           X        ,
                           Y        ,
                           Width    ,
                           Height   : Integer  ) ;
    DrawRGBBox   : procedure
                   (       PanelID  : PLWPanel ;
                           R        ,
                           G        ,
                           B        ,
                           X        ,
                           Y        ,
                           Width    ,
                           Height   : Integer  ) ;
    DrawBorder   : procedure
                   (       PanelID  : PLWPanel ;
                           Indent   ,
                           X        ,
                           Y        ,
                           Width    ,
                           Height   : Integer  ) ; // (h==0 -> divider)
    TextWidth    : function
                   (       PanelID  : PLWPanel ;
                           Text     : PChar    ) : Integer ;  // text in locale specific encoding
    DrawText     : procedure
                   (       PanelID  : PLWPanel ;
                           Text     : PChar    ;
                           Color    ,
                           X        ,
                           Y        : Integer  ) ; // text in locale specific encoding
    DispMetrics  : function
                   ( const Void                ) : PLWDisplayMetrics ; // const
  end;

  TLWControl = record
    Draw     : procedure
               (        ControlID   : PLWControl ;
                        DrawMode    : Integer    ) ; // Originally DrMode enum
    Get      : procedure
               (        ControlID   : PLWControl ;
                        CtrlTag     : Integer    ;   // Originally cTag enum
                        Value       : PLWValue   ) ;
    Set_      : procedure
               (        ControlID   : PLWControl ;
                        CtrlTag     : Integer    ;   // Originally cTag enum
                        Value       : PLWValue   ) ;
    PrivData : Pointer ;
  end;

  PLWPanelFuncs = ^TLWPanelFuncs ;
  TLWPanelFuncs = record
    Create         : function
                     (       Title    : PChar ;
                             Global   : Pointer  ) : PLWPanel  ; // Locale specific encoding
    Destroy        : procedure
                     (       PanelID  : PLWPanel ) ;
    Open           : function
                     (       PanelID  : PLWPanel ;
                             Flags    : Integer  ) : Integer   ; // Flags (see flag bits  PANF_ etc.)
    Handle         : function
                     (       PanelID  : PLWPanel ;
                             Blocking : Integer )  :  Integer  ; // Process input manually after non-blocking open, use EVNT_ bits to process async. or synchronously
    Draw           : procedure
                     (       PanelID  : PLWPanel ;
                             DrawMode : Integer  ) ;  // Originally DrMode enum
    Close          : procedure
                     (       PanelID  : PLWPanel ) ;
    Get            : procedure
                     (       PanelID  : PLWPanel ;
                             PanelTag : Integer  ; // Originally pTag enum
                             Value    : Pointer  ) ;
    Set_           : procedure
                     (       PanelID  : PLWPanel ;
                             PanelTag : Integer  ; // Originally pTag enum
                             Value    : Pointer  ) ;
    AddControl     : function
                     (       PanelID  : PLWPanel ;
                             Type_    : PChar    ;
                             Data     : PLWPanControlDesc ;
                       const Label_   : PChar    ) : PLWControl ; // Locale specific encoding
    NextControl    : function
                     (       PanelID  : PLWPanel ;
                             ControlID: PLWControl ) : PLWControl ;
    DrawFuncs      : TDrawFuncs   ;
    User_data      : Pointer      ; // Do whatcha like
    GlobalFunc     : TGlobalFunc  ; // Please set this to your GlobalFunction pointer.. at least for file req.
    DestroyControl : procedure
                     (       PanelID  : PLWPanel ;
                             ControlID : PLWControl ) ;
  end;

  PLWRaster = Pointer ;

  PLWRasterFuncs = ^TLWRasterFuncs ;
  TLWRasterFuncs = record
    DrawPixel    : procedure
                   (       RasterID : PLWRaster  ;
                           Color    ,
                           X        ,
                           Y        : Integer    ) ;
    DrawRGBPixel : procedure
                   (       RasterID : PLWRaster  ;
                           R        ,
                           G        ,
                           B        ,
                           X        ,
                           Y        : Integer    ) ;
    DrawLine     : procedure
                   (       RasterID : PLWRaster  ;
                           Color    ,
                           X        ,
                           Y        ,
                           X2       ,
                           Y2       : Integer    ) ;
    DrawBox      : procedure
                   (       RasterID : PLWRaster  ;
                           Color    ,
                           X        ,
                           Y        ,
                           Width    ,
                           Height   : Integer    ) ;
    DrawRGBBox   : procedure
                   (       RasterID : PLWRaster  ;
                           R        ,
                           G        ,
                           B        ,
                           X        ,
                           Y        ,
                           Width    ,
                           Height   : Integer    ) ;
    EraseBox     : procedure
                   (       RasterID : PLWRaster  ;
    		           X        ,
                           Y        ,
                           Width    ,
                           Height   : Integer    ) ;
    DrawBorder   : procedure
                   (       RasterID : PLWRaster  ;
                           Indent   ,
                           X        ,
                           Y        ,
                           Width    ,
                           Height   : Integer    ) ; // (h==0 -> divider)
    DrawText     : procedure
                   (       RasterID : PLWRaster  ;
                           Text     : PChar      ;
                           Color    ,
                           X        ,
                           Y        : Integer    ) ; // text in locale specific encoding

    Create       : function
                   (       Width    ,
                           Height   ,
    			   Flags    : Integer    ) : PLWRaster ;
    Destroy      : procedure
                   (       RasterID : PLWRaster  ) ;
    BlitPanel    : procedure
                   (       RasterSrcID : PLWRaster  ;
    		           RSrcX       ,
    			   RSrcY       : Integer    ;
    			   PanelDstID  : PLWPanel   ;
    			   RDestX      ,
                           RDestY      ,
                           RWidth      ,
                           RHeight     : Integer  ) ;
    BlitRaster   : procedure
                   (       RasterSrcID : PLWRaster  ;
                           RSrcX       ,
                           RSrcY       : Integer    ;
                           RasterDstID : PLWRaster  ;
                           RDestX      ,
                           RDestY      ,
                           RWidth      ,
                           RHeight     : Integer    ) ;
  end;

  PLWContextMenuFuncs = ^TLWContextMenuFuncs ;
  TLWContextMenuFuncs = record
    CMenuCreate : function
                  (       Desc         : PLWPanPopupDesc ;
                          UserData     : Pointer         ) : PLWContextMenu;
    CMenuDeploy : function
                  (       MenuID       : PLWContextMenu  ;
                          PanelID      : PLWPanel        ;
                          Item         : Integer         ) : Integer ; // item==-1 for no choice initially and/or on return
    CMenuDestroy: procedure
                  (       MenuID       : PLWContextMenu  ) ;
  end;

  PLWPanMenuDesc = ^TLWPanMenuDesc ;
  TLWPanMenuDesc = record
    // Returns number of items available
    CountFn     : function
                  (       MenuID      : Pointer  ) : Integer ;
    // Returns the display string for a particular item in a locale specific encoding
    NameFn      : function
                  (       MenuID      : Pointer  ;
                          ItemN       : Integer  ) : PChar;
    // Returns user data for the submenu (use it to identify which submenu being processed)
    SubmenuFn   : function
                  (       MenuID      : Pointer  ;
                          SubMenu     : Integer  ) : Pointer ; // added in version 2
    // Returns PANELMENUFLAG_ flags for a particular item
    // Setting both the selected and unselected bits imply a mixed selection state
    FlagsFn     : function
                  (       MenuID     : Pointer  ;
                          ItemN      : Integer  ) : Integer ; // added in version 2
    // Returns an array of integers, where 0 is a menu item,
    // and !0 is a menu item with a trailing separator
    SeparatorFn : function
                  (       MenuID     : Pointer  ) : PInteger ; // added in version 2
  end;

  PLWPanelMenuFuncs = ^TLWPanelMenuFuncs ;
  TLWPanelMenuFuncs = record
    MenuCreate    : function
                  (       Desc       : PLWPanMenuDesc ;
    			          UserData   : Pointer        ) : PLWPanelMenu;
    // Item := -1 for no choice initially and/or on return
    MenuDeploy    : function
                  (       MenuID     : PLWPanelMenu   ;
                          PanelID    : PLWPanel       ;
    					  Item       : Integer        ) : Integer ;
    MenuDestroy   : procedure
                  (       MenuID     : PLWPanelMenu   ) ;
    // User data of selection when deploy returns >= 0.
    MenuSelection : function
                  (       MenuID     : PLWPanelMenu   ) : Pointer ;
  end;

  function RGB
           ( R  ,
             G  ,
             B  : Integer ) : UInt32 ;

  function TRUECOLOR
           ( DM : PLWDisplayMetrics ) : Integer ;

  function PALETTESIZE
           ( DM : PLWDisplayMetrics ) : Integer ;

  { Utility function for Input Qualifiers }
  function RCLICK
           ( MouseCode : Integer ) : Boolean ;
  function LCLICK
           ( MouseCode : Integer ) : Boolean ;
  function MCLICK
           ( MouseCode : Integer ) : Boolean ;


implementation

function RGB(R, G, B: Integer): UInt32;
begin
  Result := UInt32( ((R) shl 16) or ((b) shl 8) or (g) or $1000000 ) ;
end;

function TRUECOLOR(DM: PLWDisplayMetrics): Integer;
begin
  if ( DM^.Depth = 1) then
    Result := 1
  else
    Result := 0 ;
end;

function PALETTESIZE(DM: PLWDisplayMetrics): Integer;
begin
  if ( DM^.Depth = 1) then
    Result := 1 shl 24
  else
    Result := 1 shl DM^.Depth ;
end;

function RCLICK(MouseCode: Integer): Boolean;
begin
  If ((MouseCode = MOUSE_LEFT) and (MouseCode = MOUSE_MID)) then
    Result := True
  else
    Result := False ;
end;

function LCLICK(MouseCode: Integer): Boolean;
begin
  If ((MouseCode = MOUSE_LEFT) and ( not (MouseCode = MOUSE_MID))) then
    Result := True
  else
    Result := False ;
end;

function MCLICK(MouseCode: Integer): Boolean;
begin
  If ((not (MouseCode = MOUSE_LEFT)) and (MouseCode = MOUSE_MID)) then
    Result := True
  else
    Result := False ;
end;

end.

